from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.db import transaction
from django.core.files.storage import default_storage
import json
import os
from datetime import datetime
from django.utils import timezone
from .models import Post, PostLike, Comment, Tag
from .models import HomeBanner
from django.utils.html import escape
from django.db.models import Count
import math
import urllib.request
import urllib.parse
import hmac
import hashlib
import base64
from email.utils import formatdate


@csrf_exempt
@require_http_methods(['GET', 'POST'])
@login_required
def post_list_create(request):
    """获取动态列表和创建动态"""
    if request.method == 'GET':
        # 获取动态列表
        try:
            page = int(request.GET.get('page', 1))
            limit = int(request.GET.get('limit', 20))
            order = (request.GET.get('order') or '').strip()  # 支持按点赞排序：order=likes/hot
            if page < 1:
                page = 1
            if limit < 1 or limit > 100:
                limit = 20
            
            offset = (page - 1) * limit
            
            posts_qs = Post.objects.select_related('user__profile').all()
            tag_name = request.GET.get('tag')
            tags_param = request.GET.get('tags')
            if tag_name:
                posts_qs = posts_qs.filter(tags__name=tag_name)
            elif tags_param:
                names = [t.strip() for t in tags_param.split(',') if t.strip()]
                if names:
                    posts_qs = posts_qs.filter(tags__name__in=names).distinct()
            # 为支持多种排序策略，先不切片，统一在内存排序后再分页
            posts = posts_qs.order_by('-created_at')
            
            def haversine(lat1,lng1,lat2,lng2):
                R=6371000.0
                phi1=math.radians(lat1); phi2=math.radians(lat2)
                dphi=math.radians(lat2-lat1); dlambda=math.radians(lng2-lng1)
                a=math.sin(dphi/2)**2+math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
                c=2*math.atan2(math.sqrt(a),math.sqrt(1-a)); return R*c
            u_lat = getattr(getattr(request.user, 'profile', None), 'lat', None)
            u_lng = getattr(getattr(request.user, 'profile', None), 'lng', None)
            post_list = []
            now = timezone.now()
            try:
                gravity = float(request.GET.get('gravity', 1.8))
            except (TypeError, ValueError):
                gravity = 1.8
            for post in posts:
                # 获取点赞数量
                like_count = PostLike.objects.filter(post=post).count()
                # 获取评论数量
                comment_count = Comment.objects.filter(post=post).count()
                # 检查当前用户是否点赞
                is_liked = PostLike.objects.filter(post=post, user=request.user).exists()
                
                avatar_url = None
                try:
                    if post.user and getattr(post.user, 'profile', None):
                        avatar_url = post.user.profile.avatar
                except Exception:
                    avatar_url = None
                distance_km = None
                try:
                    if u_lat is not None and u_lng is not None and post.lat is not None and post.lng is not None:
                        d = haversine(float(u_lat), float(u_lng), float(post.lat), float(post.lng))
                        distance_km = round(d/1000.0, 3)
                except Exception:
                    distance_km = None
                # 推荐分数（Gravity Decay Algorithm）
                try:
                    dt = (now - post.created_at).total_seconds() / 3600.0
                    P = (like_count or 0) + 2 * (comment_count or 0)
                    score = (P + 1.0) / pow((dt + 2.0), gravity)
                except Exception:
                    score = 0.0

                post_list.append({
                    'post_id': post.post_id,
                    'user_id': (post.user.id if post.user else None),
                    'username': (post.user.username if post.user else '未知用户'),
                    'content': post.content,
                    'image_urls': post.image_urls or [],
                    'created_at': post.created_at.isoformat(),
                    'like_count': like_count,
                    'comment_count': comment_count,
                    'is_liked': is_liked,
                    'avatar_url': avatar_url,
                    'tags': [t.name for t in post.tags.all()],
                    'lat': post.lat,
                    'lng': post.lng,
                    'city': post.city,
                    'province': post.province,
                    'nation': post.nation,
                    'distance_km': distance_km,
                    'score': score
                })
            
            # 排序策略
            ol = order.lower()
            if ol in ['likes', 'hot']:
                post_list.sort(key=lambda x: (x['like_count'], x['created_at']), reverse=True)
            elif ol in ['recommended', 'rec']:
                post_list.sort(key=lambda x: (x['score'], x['created_at']), reverse=True)
            elif ol in ['nearby', 'distance']:
                # 优先有距离的数据，其次按距离升序，再次按时间降序
                post_list.sort(key=lambda x: (
                    0 if (x.get('distance_km') is not None) else 1,
                    x.get('distance_km') if (x.get('distance_km') is not None) else float('inf'),
                    x['created_at']
                ))
            else:
                post_list.sort(key=lambda x: x['created_at'], reverse=True)

            # 分页切片
            sliced = post_list[offset:offset + limit]

            return JsonResponse({
                'code': 200,
                'message': '获取动态列表成功',
                'data': {
                    'posts': sliced,
                    'total': len(post_list),
                    'page': page,
                    'limit': limit
                }
            })
            
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'获取动态列表失败: {str(e)}',
                'data': None
            }, status=500)
    
    elif request.method == 'POST':
        # 创建动态
        try:
            data = json.loads(request.body)
            content = data.get('content', '').strip()
            image_urls = data.get('image_urls', [])
            tags_input = data.get('tags', [])
            lat = data.get('lat')
            lng = data.get('lng')
            city = (data.get('city') or '').strip() or None
            province = (data.get('province') or '').strip() or None
            nation = (data.get('nation') or '').strip() or None
            
            if not content and not image_urls:
                return JsonResponse({
                    'code': 400,
                    'message': '动态内容或图片不能同时为空',
                    'data': None
                }, status=400)
            
            # 创建动态
            try:
                lat = float(lat) if lat is not None else None
                lng = float(lng) if lng is not None else None
            except (TypeError, ValueError):
                lat = None; lng = None
            post = Post.objects.create(
                user=request.user,
                content=content if content else None,
                image_urls=image_urls if image_urls else None,
                lat=lat,
                lng=lng,
                city=city,
                province=province,
                nation=nation
            )
            try:
                if isinstance(tags_input, list):
                    for name in tags_input:
                        if not isinstance(name, str):
                            continue
                        n = name.strip()
                        if not n:
                            continue
                        tag_obj, _ = Tag.objects.get_or_create(name=n)
                        post.tags.add(tag_obj)
            except Exception:
                pass
            
            from rewards.utils import award_points
            award_points(request.user, 5, 'post_create', post.post_id)
            return JsonResponse({
                'code': 201,
                'message': '创建动态成功',
                'data': {
                    'post_id': post.post_id,
                    'user_id': post.user.id,
                    'username': post.user.username,
                    'content': post.content,
                    'image_urls': post.image_urls or [],
                    'created_at': post.created_at.isoformat(),
                    'lat': post.lat,
                    'lng': post.lng,
                    'city': post.city,
                    'province': post.province,
                    'nation': post.nation
                }
            }, status=201)
            
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'创建动态失败: {str(e)}',
                'data': None
            }, status=500)


@csrf_exempt
@require_http_methods(['POST'])
@login_required
def polish_text(request):
    try:
        payload = json.loads(request.body or '{}')
        text = str(payload.get('text') or '').strip()
        if not text:
            return JsonResponse({'code': 400, 'message': '缺少text', 'data': None}, status=400)
        # 优先走星火开放HTTP接口（与OpenAI兼容），参考碳足迹实现
        http_password = (
            os.environ.get('SPARK_API_PASSWORD')
            or os.environ.get('SPARK_HTTP_PASSWORD')
            or os.environ.get('SPARK_APIPASSWORD')
            or ''
        )
        http_base = os.environ.get('SPARK_HTTP_BASE_URL') or 'https://spark-api-open.xf-yun.com'
        http_path = '/v1/chat/completions'
        if http_password:
            # 先尝试 open 域名 + Bearer
            try:
                endpoint = http_base.rstrip('/') + http_path
                body = json.dumps({
                    "model": os.environ.get('SPARK_HTTP_MODEL') or 'lite',
                    "messages": [
                        {"role": "system", "content": "请润色以下中文动态文本，保持意思不变、简洁自然，避免夸张。仅返回润色后的文本。"},
                        {"role": "user", "content": text}
                    ],
                    "temperature": 0.3,
                    "max_tokens": 800
                }).encode('utf-8')
                req = urllib.request.Request(endpoint, data=body)
                req.add_header('Content-Type', 'application/json')
                req.add_header('Authorization', f'Bearer {http_password}')
                with urllib.request.urlopen(req, timeout=10) as resp:
                    raw = resp.read().decode('utf-8')
                    data = json.loads(raw)
                content = ((data.get('choices') or [{}])[0].get('message') or {}).get('content')
                result_text = (content or '').strip() or text
                return JsonResponse({'code': 200, 'message': '润色成功', 'data': {'text': result_text}})
            except Exception:
                # 回退到非 open 域名 + APIPassword 头
                try:
                    endpoint = (os.environ.get('SPARK_HTTP_BASE_URL') or 'https://spark-api.xf-yun.com').rstrip('/') + http_path
                    body = json.dumps({
                        "model": os.environ.get('SPARK_HTTP_MODEL') or 'lite',
                        "messages": [
                            {"role": "system", "content": "请润色以下中文动态文本，保持意思不变、简洁自然，避免夸张。仅返回润色后的文本。"},
                            {"role": "user", "content": text}
                        ],
                        "temperature": 0.3,
                        "max_tokens": 800
                    }).encode('utf-8')
                    req = urllib.request.Request(endpoint, data=body)
                    req.add_header('Content-Type', 'application/json')
                    req.add_header('APIPassword', http_password)
                    with urllib.request.urlopen(req, timeout=10) as resp:
                        raw = resp.read().decode('utf-8')
                        data = json.loads(raw)
                    content = ((data.get('choices') or [{}])[0].get('message') or {}).get('content')
                    result_text = (content or '').strip() or text
                    return JsonResponse({'code': 200, 'message': '润色成功', 'data': {'text': result_text}})
                except Exception:
                    pass

        # 回退到WebSocket/HTTP HMAC 接入（v3.1 chat）
        appid = os.environ.get('SPARK_APPID') or os.environ.get('SPARK_APP_ID') or ''
        api_key = os.environ.get('SPARK_API_KEY') or ''
        api_secret = os.environ.get('SPARK_API_SECRET') or ''
        spark_base = os.environ.get('SPARK_BASE_URL') or 'https://spark-api.xf-yun.com'
        spark_path = os.environ.get('SPARK_PATH') or '/v3.1/chat'
        domain = os.environ.get('SPARK_DOMAIN') or 'lite'
        if not (appid and api_key and api_secret):
            return JsonResponse({'code': 200, 'message': 'AI未配置，返回原文', 'data': {'text': text}})
        url = spark_base.rstrip('/') + spark_path
        parsed_url = urllib.parse.urlparse(url)
        host = parsed_url.netloc
        date = formatdate(usegmt=True)
        request_line = f"POST {parsed_url.path} HTTP/1.1"
        signature_origin = f"host: {host}\ndate: {date}\n{request_line}"
        signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'), hashlib.sha256).digest()
        signature = base64.b64encode(signature_sha).decode('utf-8')
        authorization = f'api_key="{api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature}"'
        payload2 = {
            "header": {"app_id": appid, "uid": "polish"},
            "parameter": {"chat": {"domain": domain, "temperature": 0.3, "max_tokens": 800}},
            "payload": {"message": {"text": [
                {"role": "system", "content": "请对以下中文动态文本进行润色，保持意思不变，简洁自然，避免夸张。仅返回润色后的文本。"},
                {"role": "user", "content": text}
            ]}}
        }
        body = json.dumps(payload2).encode('utf-8')
        req = urllib.request.Request(url, data=body)
        req.add_header('Content-Type', 'application/json')
        req.add_header('Host', host)
        req.add_header('Date', date)
        req.add_header('Authorization', authorization)
        with urllib.request.urlopen(req, timeout=10) as resp:
            raw = resp.read().decode('utf-8')
            data = json.loads(raw)
        segs = (((data.get('payload') or {}).get('choices') or {}).get('text') or [])
        result_text = ""
        for s in segs:
            result_text += (s.get('content') or '')
        result_text = (result_text or '').strip() or text
        return JsonResponse({'code': 200, 'message': '润色成功', 'data': {'text': result_text}})
    except Exception:
        # 最后一层回退：DeepSeek/OpenAI 兼容接口
        try:
            key = os.environ.get('DEEPSEEK_API_KEY') or os.environ.get('AI_API_KEY') or ''
            base = os.environ.get('DEEPSEEK_BASE_URL') or os.environ.get('AI_BASE_URL') or 'https://api.deepseek.com'
            model = os.environ.get('DEEPSEEK_MODEL') or os.environ.get('AI_MODEL') or 'deepseek-chat'
            if key:
                endpoint = base.rstrip('/') + '/v1/chat/completions'
                payload = {
                    "model": model,
                    "messages": [
                        {"role": "system", "content": "用中文润色用户文本，确保意思不变且自然简洁，只返回润色后的文本。"},
                        {"role": "user", "content": text}
                    ],
                    "temperature": 0.3,
                    "max_tokens": 800
                }
                body = json.dumps(payload).encode('utf-8')
                req = urllib.request.Request(endpoint, data=body)
                req.add_header('Content-Type', 'application/json')
                req.add_header('Authorization', f'Bearer {key}')
                with urllib.request.urlopen(req, timeout=10) as resp:
                    raw = resp.read().decode('utf-8')
                    data = json.loads(raw)
                content = ((data.get('choices') or [{}])[0].get('message') or {}).get('content')
                result_text = (content or '').strip() or text
                return JsonResponse({'code': 200, 'message': '润色成功', 'data': {'text': result_text}})
        except Exception:
            pass
        return JsonResponse({'code': 200, 'message': 'AI服务不可用，使用原文', 'data': {'text': text}})


@csrf_exempt
@require_http_methods(['GET', 'DELETE'])
@login_required
def post_detail(request, post_id):
    """获取动态详情和删除动态"""
    try:
        post = Post.objects.get(post_id=post_id)
    except ObjectDoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '动态不存在',
            'data': None
        }, status=404)
    
    if request.method == 'GET':
        # 获取动态详情
        like_count = PostLike.objects.filter(post=post).count()
        comment_count = Comment.objects.filter(post=post).count()
        is_liked = PostLike.objects.filter(post=post, user=request.user).exists()
        
        avatar_url = None
        try:
            if post.user and getattr(post.user, 'profile', None):
                avatar_url = post.user.profile.avatar
        except Exception:
            avatar_url = None
        # 计算距离
        def haversine(lat1,lng1,lat2,lng2):
            R=6371000.0
            phi1=math.radians(lat1); phi2=math.radians(lat2)
            dphi=math.radians(lat2-lat1); dlambda=math.radians(lng2-lng1)
            a=math.sin(dphi/2)**2+math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
            c=2*math.atan2(math.sqrt(a),math.sqrt(1-a)); return R*c
        distance_km = None
        u_lat = getattr(getattr(request.user, 'profile', None), 'lat', None)
        u_lng = getattr(getattr(request.user, 'profile', None), 'lng', None)
        try:
            if u_lat is not None and u_lng is not None and post.lat is not None and post.lng is not None:
                d = haversine(float(u_lat), float(u_lng), float(post.lat), float(post.lng))
                distance_km = round(d/1000.0, 3)
        except Exception:
            distance_km = None
        return JsonResponse({
                'code': 200,
                'message': '获取动态详情成功',
                'data': {
                    'post_id': post.post_id,
                    'user_id': (post.user.id if post.user else None),
                    'username': (post.user.username if post.user else '未知用户'),
                    'content': post.content,
                    'image_urls': post.image_urls or [],
                    'created_at': post.created_at.isoformat(),
                    'like_count': like_count,
                    'comment_count': comment_count,
                    'is_liked': is_liked,
                    'avatar_url': avatar_url,
                    'tags': [t.name for t in post.tags.all()],
                    'lat': post.lat,
                    'lng': post.lng,
                    'city': post.city,
                    'province': post.province,
                    'nation': post.nation,
                    'distance_km': distance_km
                }
            })
    
    elif request.method == 'DELETE':
        # 删除动态
        if post.user != request.user:
            return JsonResponse({
                'code': 403,
                'message': '只能删除自己的动态',
                'data': None
            }, status=403)
        with transaction.atomic():
            PostLike.objects.filter(post=post).delete()
            Comment.objects.filter(post=post).delete()
            post.delete()
        
        return JsonResponse({
            'code': 200,
            'message': '删除动态成功',
            'data': None
        }, status=200)


@require_http_methods(['GET'])
@login_required
def user_post_list(request):
    """获取当前用户动态列表"""
    try:
        page = int(request.GET.get('page', 1))
        limit = int(request.GET.get('limit', 20))
        if page < 1:
            page = 1
        if limit < 1 or limit > 100:
            limit = 20
        
        offset = (page - 1) * limit
        
        # 获取当前用户的动态
        posts = Post.objects.filter(user=request.user).select_related('user__profile').order_by('-created_at')[offset:offset + limit]
        
        def haversine(lat1,lng1,lat2,lng2):
            R=6371000.0
            phi1=math.radians(lat1); phi2=math.radians(lat2)
            dphi=math.radians(lat2-lat1); dlambda=math.radians(lng2-lng1)
            a=math.sin(dphi/2)**2+math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
            c=2*math.atan2(math.sqrt(a),math.sqrt(1-a)); return R*c
        u_lat = getattr(getattr(request.user, 'profile', None), 'lat', None)
        u_lng = getattr(getattr(request.user, 'profile', None), 'lng', None)
        post_list = []
        for post in posts:
            like_count = PostLike.objects.filter(post=post).count()
            comment_count = Comment.objects.filter(post=post).count()
            is_liked = PostLike.objects.filter(post=post, user=request.user).exists()
            
            avatar_url = None
            try:
                if post.user and getattr(post.user, 'profile', None):
                    avatar_url = post.user.profile.avatar
            except Exception:
                avatar_url = None
            distance_km = None
            try:
                if u_lat is not None and u_lng is not None and post.lat is not None and post.lng is not None:
                    d = haversine(float(u_lat), float(u_lng), float(post.lat), float(post.lng))
                    distance_km = round(d/1000.0, 3)
            except Exception:
                distance_km = None
            post_list.append({
                'post_id': post.post_id,
                'user_id': (post.user.id if post.user else None),
                'username': (post.user.username if post.user else '未知用户'),
                'content': post.content,
                'image_urls': post.image_urls or [],
                'created_at': post.created_at.isoformat(),
                'like_count': like_count,
                'comment_count': comment_count,
                'is_liked': is_liked,
                'avatar_url': avatar_url,
                'tags': [t.name for t in post.tags.all()],
                'lat': post.lat,
                'lng': post.lng,
                'city': post.city,
                'province': post.province,
                'nation': post.nation,
                'distance_km': distance_km
            })
        
        return JsonResponse({
            'code': 200,
            'message': '获取用户动态列表成功',
            'data': {
                'posts': post_list,
                'total': Post.objects.filter(user=request.user).count(),
                'page': page,
                'limit': limit
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'获取用户动态列表失败: {str(e)}',
            'data': None
        }, status=500)


@csrf_exempt
@require_http_methods(['POST', 'DELETE'])
@login_required
def post_like(request, post_id):
    """点赞/取消点赞动态"""
    try:
        post = Post.objects.get(post_id=post_id)
    except ObjectDoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '动态不存在',
            'data': None
        }, status=404)
    
    if request.method == 'POST':
        # 点赞动态
        try:
            # 检查是否已经点赞
            like, created = PostLike.objects.get_or_create(
                post=post,
                user=request.user
            )
            
            if created:
                return JsonResponse({
                    'code': 201,
                    'message': '点赞成功',
                    'data': {
                        'like_id': like.like_id,
                        'post_id': post.post_id,
                        'user_id': request.user.id,
                        'username': request.user.username,
                        'created_at': like.created_at.isoformat()
                    }
                }, status=201)
            else:
                return JsonResponse({
                    'code': 200,
                    'message': '已经点赞过该动态',
                    'data': None
                }, status=200)
                
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'点赞失败: {str(e)}',
                'data': None
            }, status=500)
    
    elif request.method == 'DELETE':
        # 取消点赞
        try:
            deleted_count, _ = PostLike.objects.filter(
                post=post,
                user=request.user
            ).delete()
            
            if deleted_count > 0:
                return JsonResponse({
                    'code': 200,
                    'message': '取消点赞成功',
                    'data': None
                }, status=200)
            else:
                return JsonResponse({
                    'code': 404,
                    'message': '未点赞过该动态',
                    'data': None
                }, status=404)
                
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'取消点赞失败: {str(e)}',
                'data': None
            }, status=500)


@require_http_methods(['GET'])
@login_required
def post_likes_list(request, post_id):
    """获取动态点赞列表"""
    try:
        post = Post.objects.get(post_id=post_id)
    except ObjectDoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '动态不存在',
            'data': None
        }, status=404)
    
    try:
        page = int(request.GET.get('page', 1))
        limit = int(request.GET.get('limit', 50))
        if page < 1:
            page = 1
        if limit < 1 or limit > 100:
            limit = 50
        
        offset = (page - 1) * limit
        
        # 获取点赞列表
        likes = PostLike.objects.filter(post=post).order_by('-created_at')[offset:offset + limit]
        
        like_list = []
        for like in likes:
            like_list.append({
                'like_id': like.like_id,
                'user_id': (like.user.id if like.user else None),
                'username': (like.user.username if like.user else '未知用户'),
                'created_at': like.created_at.isoformat()
            })
        
        return JsonResponse({
            'code': 200,
            'message': '获取点赞列表成功',
            'data': {
                'likes': like_list,
                'total': PostLike.objects.filter(post=post).count(),
                'page': page,
                'limit': limit
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'获取点赞列表失败: {str(e)}',
            'data': None
        }, status=500)


@csrf_exempt
@require_http_methods(['GET', 'POST'])
@login_required
def comment_list_create(request, post_id):
    """获取评论列表和创建评论"""
    try:
        post = Post.objects.get(post_id=post_id)
    except ObjectDoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '动态不存在',
            'data': None
        }, status=404)
    
    if request.method == 'GET':
        # 获取评论列表
        try:
            page = int(request.GET.get('page', 1))
            limit = int(request.GET.get('limit', 20))
            if page < 1:
                page = 1
            if limit < 1 or limit > 100:
                limit = 20
            
            offset = (page - 1) * limit
            
            comments = Comment.objects.filter(post=post).order_by('-created_at')[offset:offset + limit]
            
            comment_list = []
            for comment in comments:
                avatar_url = None
                try:
                    if comment.user and getattr(comment.user, 'profile', None):
                        avatar_url = comment.user.profile.avatar
                except Exception:
                    avatar_url = None
                comment_list.append({
                    'comment_id': comment.comment_id,
                    'post_id': comment.post.post_id,
                    'user_id': (comment.user.id if comment.user else None),
                    'username': (comment.user.username if comment.user else '未知用户'),
                    'content': comment.content,
                    'created_at': comment.created_at.isoformat(),
                    'avatar_url': avatar_url,
                    'can_delete': (comment.user == request.user) or getattr(request.user, 'is_staff', False)
                })
            
            return JsonResponse({
                'code': 200,
                'message': '获取评论列表成功',
                'data': {
                    'comments': comment_list,
                    'total': Comment.objects.filter(post=post).count(),
                    'page': page,
                    'limit': limit
                }
            })
            
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'获取评论列表失败: {str(e)}',
                'data': None
            }, status=500)
    
    elif request.method == 'POST':
        # 创建评论
        try:
            data = json.loads(request.body)
            content = data.get('content', '').strip()
            
            if not content:
                return JsonResponse({
                    'code': 400,
                    'message': '评论内容不能为空',
                    'data': None
                }, status=400)
            
            # 创建评论
            comment = Comment.objects.create(
                post=post,
                user=request.user,
                content=content
            )
            
            return JsonResponse({
                'code': 201,
                'message': '创建评论成功',
                'data': {
                    'comment_id': comment.comment_id,
                    'post_id': comment.post.post_id,
                    'user_id': comment.user.id,
                    'username': comment.user.username,
                    'content': comment.content,
                    'created_at': comment.created_at.isoformat(),
                    'avatar_url': (getattr(getattr(comment.user, 'profile', None), 'avatar', None)),
                    'can_delete': True
                }
            }, status=201)
            
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'创建评论失败: {str(e)}',
                'data': None
            }, status=500)


@csrf_exempt
@require_http_methods(['DELETE'])
@login_required
def comment_detail(request, comment_id):
    """删除评论"""
    try:
        comment = Comment.objects.get(comment_id=comment_id)
    except ObjectDoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '评论不存在',
            'data': None
        }, status=404)
    
    # 删除评论（作者或管理员可删）
    if not (comment.user == request.user or getattr(request.user, 'is_staff', False)):
        return JsonResponse({
            'code': 403,
            'message': '只能删除自己的评论',
            'data': None
        }, status=403)
    comment.delete()
    return JsonResponse({'code': 200, 'message': '删除评论成功', 'data': None})


@csrf_exempt
@require_http_methods(['POST'])
@login_required
def upload_post_images(request):
    """
    社区动态图片上传接口
    
    权限: 已登录用户
    
    参数:
        - images: 多张图片文件（支持多文件上传）
        
    返回:
        - code: 状态码
        - message: 提示信息
        - data: {
            - image_urls: 上传成功的图片URL列表
            - failed_files: 上传失败的文件名列表
        }
    """
    try:
        # 检查是否有文件上传
        if 'images' not in request.FILES:
            return JsonResponse({
                'code': 400,
                'message': '请选择要上传的图片文件',
                'data': None
            })
        
        images = request.FILES.getlist('images')  # 获取多文件列表
        
        # 验证文件类型和大小
        allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
        max_size = 10 * 1024 * 1024  # 10MB
        
        successful_urls = []
        failed_files = []
        
        for image_file in images:
            # 验证文件类型
            if image_file.content_type not in allowed_types:
                failed_files.append({
                    'filename': image_file.name,
                    'reason': '不支持的文件格式'
                })
                continue
            
            # 验证文件大小
            if image_file.size > max_size:
                failed_files.append({
                    'filename': image_file.name,
                    'reason': '文件大小超过10MB限制'
                })
                continue
            
            try:
                # 使用通用图片上传接口
                from backed.cos_utils import cos_uploader
                
                # 上传到腾讯云COS
                upload_result = cos_uploader.upload_file(
                    image_file, 
                    file_type='community', 
                    user_id=request.user.id
                )
                
                if upload_result['success']:
                    successful_urls.append(upload_result['url'])
                else:
                    require_cos = getattr(settings, 'TENCENT_COS_REQUIRE', False)
                    if require_cos:
                        failed_files.append({
                            'filename': image_file.name,
                            'reason': upload_result['message'] or 'COS未配置或上传失败'
                        })
                    else:
                        try:
                            date_folder = datetime.now().strftime('%Y%m%d')
                            rel_path = f"community/user_{request.user.id}/{date_folder}/{image_file.name}"
                            saved_path = default_storage.save(rel_path.replace('\\','/'), image_file)
                            media_url = (getattr(settings, 'MEDIA_URL', '/media/') or '/media/')
                            rel_url = media_url.rstrip('/') + '/' + saved_path.replace('\\','/')
                            url = request.build_absolute_uri(rel_url)
                            successful_urls.append(url)
                        except Exception as e:
                            failed_files.append({
                                'filename': image_file.name,
                                'reason': upload_result['message'] or f'COS未配置，且本地保存失败: {str(e)}'
                            })
                    
            except Exception as e:
                failed_files.append({
                    'filename': image_file.name,
                    'reason': f'上传失败: {str(e)}'
                })
        
        # 返回结果
        if successful_urls:
            return JsonResponse({
                'code': 200,
                'message': f'成功上传 {len(successful_urls)} 张图片，失败 {len(failed_files)} 张',
                'data': {
                    'image_urls': successful_urls,
                    'failed_files': failed_files
                }
            })
        else:
            return JsonResponse({
                'code': 400,
                'message': '所有图片上传失败',
                'data': {
                    'image_urls': [],
                    'failed_files': failed_files
                }
            })
            
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'图片上传失败: {str(e)}',
            'data': None
        })


@require_http_methods(['GET'])
@login_required
def tag_list(request):
    try:
        qs = Tag.objects.all().annotate(post_count=Count('posts')).order_by('name')
        tags = [{'name': t.name, 'post_count': t.post_count} for t in qs]
        return JsonResponse({'code': 200, 'message': '获取标签列表成功', 'data': {'tags': tags}})
    except Exception as e:
        return JsonResponse({'code': 500, 'message': f'获取标签列表失败: {str(e)}', 'data': None}, status=500)


@csrf_exempt
@require_http_methods(['GET'])
@login_required
def eco_news_list_create(request):
    """
    环保动态资讯接口改造：直接返回按点赞量排序的前6条绿色动态。
    点赞量相同按发布时间倒序。
    """
    try:
        # 统计各动态的点赞数量
        likes = PostLike.objects.values('post_id').annotate(cnt=Count('like_id'))
        like_map = {row['post_id']: row['cnt'] for row in likes}

        posts = list(Post.objects.all())

        def derive_title(content: str) -> str:
            if not content:
                return '绿色动态'
            first_line = (content or '').split('\n')[0].strip()
            return (first_line[:20] + ('…' if len(first_line) > 20 else '')) or '绿色动态'

        def derive_excerpt(content: str) -> str:
            if not content:
                return ''
            text = content.strip().replace('\r', '')
            return text[:60] + ('…' if len(text) > 60 else '')

        items = []
        for p in posts:
            cover = None
            if isinstance(p.image_urls, list) and p.image_urls:
                cover = p.image_urls[0]
            items.append({
                'post_id': p.post_id,
                'title': derive_title(p.content or ''),
                'excerpt': derive_excerpt(p.content or ''),
                'cover_url': cover,
                'created_at': p.created_at.isoformat(),
                'like_count': like_map.get(p.post_id, 0),
            })

        items.sort(key=lambda x: (x['like_count'], x['created_at']), reverse=True)
        items = items[:6]

        return JsonResponse({'code': 200, 'message': '获取绿色动态成功', 'data': {'items': items}})
    except Exception as e:
        return JsonResponse({'code': 500, 'message': f'获取绿色动态失败: {str(e)}', 'data': None}, status=500)


@csrf_exempt
@require_http_methods(['GET'])
def home_banners_view(request):
    """首页轮播图配置接口（社区模块）"""
    try:
        banners = HomeBanner.objects.filter(is_active=True).order_by('order', '-created_at')
        items = []
        for b in banners:
            img_url = None
            try:
                if b.image:
                    # 使用绝对URL，避免前端不同端口相对路径问题
                    img_url = request.build_absolute_uri(b.image.url)
                elif b.image_url:
                    # 如果是以/开头的相对路径，构建绝对URL
                    img_url = b.image_url
                    if isinstance(img_url, str) and img_url.startswith('/'):
                        img_url = request.build_absolute_uri(img_url)
            except Exception:
                img_url = b.image_url
            items.append({
                'image_url': img_url or '',
                'title': b.title,
                'slogan': b.slogan,
                'align': b.align,
                'title_color': b.title_color,
                'slogan_color': b.slogan_color,
                'title_font_size': b.title_font_size,
                'slogan_font_size': b.slogan_font_size,
                'offset_x': b.offset_x,
                'offset_y': b.offset_y,
                'show_text': bool(b.show_text),
            })
        return JsonResponse({'success': True, 'data': {'items': items}}, status=200)
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'获取轮播图失败: {str(e)}'}, status=500)


# 已移除 EcoNews 详情与上传接口
